/*
 * 版权所有 (C) 2015 知启蒙(ZHIQIM) 保留所有权利。[遇见知启蒙，邂逅框架梦]
 * 
 * https://zhiqim.org/project/zhiqim_framework/zhiqim_kernel.htm
 *
 * Zhiqim Kernel is licensed under Mulan PSL v2.
 * You can use this software according to the terms and conditions of the Mulan PSL v2.
 * You may obtain a copy of Mulan PSL v2 at:
 *          http://license.coscl.org.cn/MulanPSL2
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 * See the Mulan PSL v2 for more details.
 */
package org.zhiqim.kernel.paging;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import org.zhiqim.kernel.util.Lists;

/**
 * 分页生成器
 *
 * @version v1.0.0 @author zouzhigang 2014-2-27 新建与整理
 */
public class PageBuilder
{
    /**
     * 新建一个空的分页信息，默认第一页，指定页大小
     * 
     * @param pageSize      页码数
     * @return PageResult   结果
     */
    public static <T> PageResult<T> newResult(int pageSize)
    {
        return newResult(1, pageSize);
    }
    
    /**
     * 新建一个空的分页信息，该方法一般用于过滤页
     * 
     * @param pageNo        页码数
     * @param pageSize      页大小
     * @return PageResult   结果
     */
    public static <T> PageResult<T> newResult(int pageNo, int pageSize)
    {
        return new PageResult<T>(0, pageNo, pageSize, new ArrayList<T>());
    }
    
    /**
     * 新建一个只有一条的分页信息，默认第一页，指定页大小
     * 
     * @param pageSize      页大小
     * @param obj           对象
     * @return PageResult   结果
     */
    public static <T> PageResult<T> newResult(int pageSize, T obj)
    {
        return newResult(1, pageSize, obj);
    }
    
    /**
     * 新建一个只有一条的分页信息，指定页码和页大小
     * 
     * @param pageNo        页码数
     * @param pageSize      页大小
     * @return PageResult   结果
     */
    public static <T> PageResult<T> newResult(int pageNo, int pageSize, T obj)
    {
        List<T> list = new ArrayList<T>(1);
        list.add(obj);
        return new PageResult<T>(1, pageNo, pageSize, list);
    }
    
    /**
     * 新建一个多条的分页信息，默认第一页，指定页大小
     * 
     * @param pageSize      页码数
     * @param objs          对象数组
     * @return PageResult   结果
     */
    public static <T> PageResult<T> newResult(int pageSize, T[] objs)
    {
        return newResult(1, pageSize, objs);
    }
    
    /**
     * 新建一个多条的分页信息，指定页码和页大小
     * 
     * @param pageNo        页码数
     * @param pageSize      页大小
     * @return PageResult   结果
     */
    public static <T> PageResult<T> newResult(int pageNo, int pageSize, T[] objs)
    {
        List<T> list = new ArrayList<T>(objs.length);
        for (T obj : objs)
            list.add(obj);
        
        return new PageResult<T>(objs.length, pageNo, pageSize, list);
    }
    
    /**
     * 通过已知列表和总数，新建分页信息
     * 
     * @param total         总数目
     * @param pageNo        页码数
     * @param pageSize      页大小
     * @param list          列表
     * @return PageResult   结果
     */
    public static <T> PageResult<T> newResult(int total, int pageNo, int pageSize, List<T> list)
    {
        return new PageResult<T>(total, pageNo, pageSize, list);
    }
    
    /**
     * 通过已知列表和总数，新建分页信息
     * 
     * @param hasNext       是否有下一页
     * @param pageNo        页码数
     * @param pageSize      页大小
     * @param list          列表
     * @return PageResult   结果
     */
    public static <T> PageResult<T> newResult(boolean hasNext, int pageNo, int pageSize, List<T> list)
    {
        return new PageResult<T>(hasNext, pageNo, pageSize, list);
    }
    
    /**
     * 通过当前页和页码数获取分页对象
     * 
     * @param pageNo        页码数
     * @param pageSize      页大小
     * @param list          列表
     * @return              分页列表
     */
    public static <T> List<T> pageList(int pageNo, int pageSize, List<T> list)
    {
        if (list == null || list.isEmpty())
            return new ArrayList<>();
        
        int offset = (pageNo - 1) * pageSize;
        int size = list.size();
        if (size <= offset)
            return new ArrayList<>();
            
        List<T> subList = (size <= offset+pageSize) ? list.subList(offset, size) : list.subList(offset, offset+pageSize);
        return Lists.trim(subList);
    }
    
    /**
     * 通过当前页和页码数获取分页对象
     * 
     * @param pageNo        页码数
     * @param pageSize      页大小
     * @param collection    列表
     * @return              分页列表
     */
    public static <T> List<T> pageList(int pageNo, int pageSize, Collection<T> collection)
    {
        if (collection == null || collection.isEmpty())
            return new ArrayList<>();
        
        return pageList(pageNo, pageSize, new ArrayList<T>(collection));
    }
    
    /**
     * 通过当前页和页码数获取分页对象
     * 
     * @param pageNo        页码数
     * @param pageSize      页大小
     * @param list          列表
     * @return PageResult   结果
     */
    public static <T> PageResult<T> pageResult(int pageNo, int pageSize, List<T> list)
    {
        if (list == null || list.isEmpty())
            return newResult(0, pageNo, pageSize, new ArrayList<T>());
        
        List<T> subList = pageList(pageNo, pageSize, list);
        return new PageResult<T>(list.size(), pageNo, pageSize, subList);
    }
    
    /**
     * 通过当前页和页码数获取分页对象
     * 
     * @param pageNo        页码数
     * @param pageSize      页大小
     * @param collection    列表
     * @return PageResult   结果
     */
    public static <T> PageResult<T> pageResult(int pageNo, int pageSize, Collection<T> collection)
    {
        if (collection == null || collection.isEmpty())
            return newResult(0, pageNo, pageSize, new ArrayList<T>());
        
        return pageResult(pageNo, pageSize, new ArrayList<>(collection));
    }
}
